토폴로지 기반 라우팅

개요

클라우드 환경에서 클러스터를 운영하다보면, 어느 지역에서 어떤 가용영역이 있어서 어떻게 트래픽을 분산해야 효율적인지에 대한 문제가 중요해진다.

예를 들어보자.
EKS를 운영하는데 3개의 AZ에 전부 노드를 배치했고, 서비스 하나가 모든 az에 위치한 파드를 백엔드로 두고 있다.
이때 1 az에 있는 다른 파드가 서비스에 트래픽을 보냈다.
기본적으로 이 요청은 서비스의 트래픽 분산 규칙에 정의된 대로, 다양한 az에 위치한 백엔드로 분산된다..
즉, 1 az에 있는 백엔드로 가야 별도의 비용이 발생하지 않는데 멋대로 3az로 트래픽이 가버리는 상황이 발생할 수도 있다는 말이다.
일단 트래픽 처리 속도도 느릴 것이고, 추가적으로 크로스존 비용까지 감당해야 하는 웃픈 상황이 나올 수 있다.
물론 분산 처리를 통해 효율적으로 트래픽을 처리하게 될 수도 있지만, 오히려 이렇게 비효율적인 상황 역시 충분히 나올 수 있다는 것이다.

이에 대한 세세한 설정을 하기 위해 등장한 것이 바로 토폴로지 기반 라우팅이다.
최대한 같은 존으로 트래픽을 보냄으로써 처리 효율성과 비용 효율성을 챙기는 것을 도와준다!

참고로 이것은 1.27버전까지 Topology Aware Hints라고 불렀다.
service.kubernetes.io/topology-aware-hints이라는 어노테이션을 사용하는 방식이었다.

현재는 서비스에 service.kubernetes.io/topology-mode : Auto라는 어노테이션을 다는 방식으로 활성화할 수 있다.

동작 방식

서비스에 엔드포인트슬라이스를 연결하는 컨트롤러가 토폴로지에 대한 정보를 가지고 엔드포인트 슬라이스를 세분화시켜준다.

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-hints
  labels:
    kubernetes.io/service-name: example-svc
addressType: IPv4
ports:
  - name: http
    protocol: TCP
	    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    zone: zone-a
    hints:
      forZones:
        - name: "zone-a"

이런 식으로 엔드포인트슬라이스 오브젝트가 만들어지게 되는 것이다.
구체적으로 region과 zone에 대한 정보를 활용하는 것이다.
맨 아래 hints 필드를 통해 어떤 존의 노드에서 이 엔포슬을 썼으면 하는지 작성해준다.
무조건 1az의 엔드포인트들에 대해 1az만 힌트로 달아두는 게 아니라 비례적으로 분산을 해주는 식이다.

그러면 각 노드의 kube-proxy가 이 힌트를 활용해 노드의 분산 규칙을 작성한다.
힌트에 자신의 존이 적혔다면 해당 엔포슬을 사용하는 건데, 비례적 분산이기에 결과적으로는 다른 존으로 트래픽이 갈 수도 있다.

각 zone에 충분한 수의 엔드포인트가 있을 때, 엔포슬 컨트롤러가 알아서 엔포슬을 세분화시킨다.

좋은 상황

같은 토폴로지로 트래픽을 보내는 게 아무때나 이득을 보는 게 절대 아니다.
그럼 이 기능을 언제 사용하는 것이 좋을까?

In a three zone cluster, this means 9 or more endpoints. If there are fewer than 3 endpoints per zone, there is a high (≈50%) probability that the EndpointSlice controller will not be able to allocate endpoints evenly and instead will fall back to the default cluster-wide routing approach.

The "Auto" heuristic attempts to proportionally allocate a number of endpoints to each zone. Note that this heuristic works best for Services that have a significant number of endpoints.

컨트롤러는 각 존에 비례적으로 엔드포인트를 할당한다.
이 비율은 해당 존에 있는 노드, 혹은 cpu 개수를 기반으로 한다.
가령 한 존에 2개의 cpu가 있고 다른 존에는 하나만 있다고 있다면, 컨트롤러는 2개가 있는 쪽에 더 많은 엔드포인트를 부여한다.

프록시는 엔포슬 오브젝트에 적힌 힌트를 기반으로 엔드포인트를 필터링한다.

보험

이 라우팅은 엄격하게 적용되도록 설계되지 않았다.
컨트롤 플레인과 프록시는 여기에 몇 가지 보험 규칙을 걸어뒀다.

제약

커스텀 휴리스틱

heuristic

휴리스틱은 보통 가능한 최선책, 러프한 접근법 등을 뜻하는 표현으로 이해하고 있다.
적절하게 번역할 단어를 잘 못 찾겠다.

모든 케이스에 잘 들어맞는 해결책은 존재하지 않을 것이다.
그래서 관련한 설정을 1.27부터 커스텀할 수 있도록 지원하려한다는 듯..?

관련 문서

이름 noteType created

참고